package top.byteio.common.core.utils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;

/**
 * JSON文件读写工具类（基于Jackson实现）
 * 支持：对象写入JSON文件、从JSON文件读取对象、集合读写等
 */
@SuppressWarnings("all")
public class JsonFileUtils {

    // 静态Jackson核心对象（线程安全，全局复用）
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    // 私有构造方法，禁止实例化
    private JsonFileUtils() {}

    static {
        // 配置JSON格式化输出（可选，美化JSON格式）
        OBJECT_MAPPER.writerWithDefaultPrettyPrinter();
        // 支持日期格式自动转换（可选，根据需求配置）
        OBJECT_MAPPER.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        // 忽略未知属性（可选，根据需求配置）
        OBJECT_MAPPER.registerModule(new JavaTimeModule());
    }

    /**
     * 将Java对象写入JSON文件
     * @param filePath 目标文件路径（如："data/user.json"）
     * @param obj 要写入的对象（支持任意可序列化的Java对象）
     * @throws IOException 当文件写入失败时抛出（如权限不足、路径错误）
     */
    public static void write(String filePath, Object obj) throws IOException {
        // 确保父目录存在
        createParentDirs(filePath);
        // 写入文件
        OBJECT_MAPPER.writeValue(new File(filePath), obj);
    }

    /**
     * 从JSON文件读取Java对象
     * @param filePath JSON文件路径
     * @param clazz 目标对象的类类型（如：User.class）
     * @return 解析后的Java对象
     * @throws IOException 当文件读取失败或JSON解析错误时抛出
     */
    public static <T> T read(String filePath, Class<T> clazz) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new IOException("文件不存在：" + filePath);
        }
        return OBJECT_MAPPER.readValue(file, clazz);
    }

    /**
     * 将集合对象写入JSON文件（如List<User>）
     * @param filePath 目标文件路径
     * @param list 要写入的集合
     * @throws IOException 当文件写入失败时抛出
     */
    public static <T> void writeList(String filePath, List<T> list) throws IOException {
        createParentDirs(filePath);
        OBJECT_MAPPER.writeValue(new File(filePath), list);
    }

    /**
     * 从JSON文件读取集合对象（如List<User>）
     * @param filePath JSON文件路径
     * @param typeReference 集合的泛型类型引用（如：new TypeReference<List<User>>() {}）
     * @return 解析后的集合对象
     * @throws IOException 当文件读取失败或JSON解析错误时抛出
     */
    public static <T> List<T> readList(String filePath, TypeReference<List<T>> typeReference) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new IOException("文件不存在：" + filePath);
        }
        return OBJECT_MAPPER.readValue(file, typeReference);
    }

    /**
     * 创建文件的父目录（如果不存在）
     * @param filePath 文件路径
     */
    private static void createParentDirs(String filePath) {
        File file = new File(filePath);
        File parentDir = file.getParentFile();
        if (parentDir != null && !parentDir.exists()) {
            // 递归创建父目录
            parentDir.mkdirs();
        }
    }
}
